p->size = (exit_qualification & 7) + 1;
if (test_bit(4, &exit_qualification)) {
+ unsigned long eflags;
+
+ __vmread(GUEST_EFLAGS, &eflags);
+ p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
p->pdata_valid = 1;
p->u.pdata = (void *) ((p->dir == IOREQ_WRITE) ?
regs->esi
struct domain *d = ed->domain;
execution_context_t *ec = get_execution_context();
unsigned long old_eax;
- unsigned long eflags;
- int dir;
+ int sign;
/* clear the pending event */
ed->vcpu_info->evtchn_upcall_pending = 0;
return;
}
- __vmread(GUEST_EFLAGS, &eflags);
- dir = (eflags & X86_EFLAGS_DF);
+ sign = (p->df) ? -1 : 1;
+ if (p->port_mm) {
+ if (p->pdata_valid) {
+ ec->esi += sign * p->count * p->size;
+ ec->edi += sign * p->count * p->size;
+ } else {
+ if (p->dir == IOREQ_WRITE) {
+ return;
+ }
+ }
+ }
if (p->dir == IOREQ_WRITE) {
if (p->pdata_valid) {
- if (!dir)
- ec->esi += p->count * p->size;
- else
- ec->esi -= p->count * p->size;
+ ec->esi += sign * p->count * p->size;
ec->ecx -= p->count;
}
return;
} else {
if (p->pdata_valid) {
- if (!dir)
- ec->edi += p->count * p->size;
- else
- ec->edi -= p->count * p->size;
+ ec->edi += sign * p->count * p->size;
ec->ecx -= p->count;
return;
}
u64 data; /* data */
void *pdata; /* pointer to data */
} u;
- u8 state:5;
+ u8 state:4;
u8 pdata_valid:1; /* if 1, use pdata above */
u8 dir:1; /* 1=read, 0=write */
u8 port_mm:1; /* 0=portio, 1=mmio */
+ u8 df:1;
} ioreq_t;
#define MAX_VECTOR 256